home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-02 | 6.1 KB | 183 lines | [TEXT/CCL2] |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; pict-view.lisp
- ;;
- ;; these define a subclass of pict-view called pict-view, which cache their
- ;; image as a pict.
-
- (in-package :ccl)
-
- (export '(pict-view with-pict-view with-rectangle-arg set-pict-cache view-close erase-view)
- 'ccl)
-
- (eval-when (eval compile)
- (require :deftrap)
- (require-interface :quickdraw))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;
- ;;; macros defined first
-
- (defmacro with-rectangle-arg ((var left &optional top right bottom) &body body)
- "takes a rectangle, two points, or four coordinates and makes a rectangle.
- body is evaluated with VAR bound to that rectangle."
- (let ((left-var (make-symbol "LEFT"))
- (top-var (make-symbol "TOP"))
- (right-var (make-symbol "RIGHT"))
- (bottom-var (make-symbol "BOTTOM")))
- `(let ((,left-var ,left)
- (,top-var ,top)
- (,right-var ,right)
- (,bottom-var ,bottom))
- (call-with-rectangle-arg
- #'(lambda (,var)
- (declare (downward-function))
- ,@body)
- ,left-var ,top-var ,right-var ,bottom-var))))
-
- (defun call-with-rectangle-arg (thunk left top right bottom)
- (rlet ((var :rect))
- (cond (bottom
- (rset var rect.topleft (make-point left top))
- (rset var rect.bottomright (make-point right bottom)))
- (right
- (error "Illegal rectangle arguments: ~s ~s ~s ~s"
- left top right bottom))
- (top
- (rset var rect.topleft (make-point left nil))
- (rset var rect.bottomright (make-point top nil)))
- (t (%setf-macptr var left)))
- (funcall thunk var)))
-
- ;; the macro with-pict-view evaluates forms while saving a picture
- ;; in the view-pict cache
-
- (defmacro with-pict-view (view bottom-right &body body)
- `(without-interrupts ;; don't want to redraw window now!
- (with-focused-view view
- (erase-view ,view)
- (unwind-protect (progn
- (record-picture ,view ,bottom-right)
- ,@body)
- (set-pict-cache ,view (get-picture ,view))))))
-
- (defmacro with-view (view &body body)
- "Like with-view except that the clip-rect is not set"
- `(with-port (wptr ,view)
- ,@body))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;
- ;;; the class pict-view is defined here
-
- (defclass pict-view (simple-view)
- ((view-pict :accessor view-pict
- :initarg :view-pict
- :initform nil)))
-
- (defmethod record-picture ((view pict-view) bottom-right)
- (let ((wptr (wptr view)))
- (unless (%null-ptr-p (rref wptr windowRecord.picsave))
- (error "A picture may not be started for window: ~a.
- since one is already started" view))
- (rlet ((r ((r :rect))))
- (rset r rect.topleft #@(0 0))
- (rset r rect.bottomright bottom-right)
- (#_cliprect r)
- (setf (view-get view 'my-hPic) (#_OpenPicture r)))
- nil))
-
- (defmethod display-picture ((view pict-view) picture)
- "A method internal to pict-views"
- (let ((topleft (rref picture picture.picFrame.topleft))
- (botright (rref picture picture.picFrame.bottomright)))
- (with-rectangle-arg (r topleft botright)
- (with-focused-view view
- (rlet ((cr :rect :topleft (view-origin view) :bottomright (add-points (view-origin view) (view-size view))))
- (#_cliprect cr))
- (#_DrawPicture picture r))))
- picture)
-
-
- (defmethod erase-view ((view pict-view))
- "Calls erase-rect on the view rect defined by view"
- (let ((view-origin (view-scroll-position view)))
- (with-rectangle-arg (r view-origin (add-points (view-size view) view-origin))
- (with-focused-view view
- (#_EraseRect r)))))
-
- (defmethod clear-pict-cache ((view pict-view))
- "Clears the view-pict cache."
- (let ((pict (view-pict view)))
- (when pict
- (#_KillPicture pict)
- (setf (view-pict view) nil)))
- (erase-view view))
-
- (defmethod set-pict-cache ((view pict-view) pict)
- "Draws pict in view and saves it in the view-pict cache"
- (clear-pict-cache view)
- (setf (view-pict view) pict)
- (display-picture view pict))
-
- (defmethod view-draw-contents ((view pict-view))
- "Draw the pict cached in view-pict"
- (let ((pict (view-pict view)))
- (when pict
- (display-picture view pict)))
- (call-next-method))
-
- (defmethod field-size ((view pict-view))
- "Returns the size of the pict, if there is one"
- (let ((pict (view-pict view)))
- (if pict
- (rref pict picture.picFrame.bottomright)
- (call-next-method))))
-
- (defmethod view-close ((view pict-view))
- "Deallocates the pict cache"
- (clear-pict-cache view)
- ; (call-next-method)
- )
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;
- ;;; Pictures get special treatment. The following are used to record and display pictures;
- ;;; they handle the clip-region properly.
- ;;;
- ;;; The following have been modified for internal use by pict-views. They should
- ;;; not be used for drawing into a pict-view
-
- (defmethod get-picture ((view simple-view))
- (let ((my-hPic (view-get view 'my-hPic))
- (wptr (wptr view)))
- (if (and my-hPic (not (%null-ptr-p (rref wptr windowRecord.picSave))))
- (prog1
- my-hPic
- (with-port wptr (#_ClosePicture))
- (setf (view-get view 'my-hPic) nil))
- (error "Picture for window: ~a is not started" view))))
-
- (defmethod draw-picture ((view pict-view) picture &optional left top right bottom)
- (cond ((not left)
- (setq left (rref picture picture.picFrame.topleft)
- top (rref picture picture.picFrame.bottomright)))
- ((pointerp left)
- ()) ;everythings fine
- ((and (not right)
- (not top))
- (setq top
- (add-points left
- (subtract-points
- (rref picture picture.picframe.bottomright)
- (rref picture picture.picframe.topleft))))))
- (with-rectangle-arg (r left top right bottom)
- (with-view view
- (#_DrawPicture picture r)))
- picture)
-
- (defun kill-picture (picture)
- (#_KillPicture picture))
-
- (provide :pict-views)
-